package org.bing.zion.core;

import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;

import org.bing.engine.common.logging.Log;
import org.bing.engine.common.logging.LogFactory;
import org.bing.zion.helper.KeyValuePair;


public class Performer implements Runnable {
	private static final Log logger = LogFactory.getLog(Performer.class);
	private final BlockingQueue<KeyValuePair<Session, Object>> messages = new LinkedBlockingQueue<KeyValuePair<Session, Object>>(64 * 1024);

	// TODO fix size, configurable
	public Performer() {
	}

	public void perform(Session session, Object msg) {
		messages.offer(new KeyValuePair<Session, Object>(session, msg));
	}

	public void run() {
		for (;;) {
			KeyValuePair<Session, Object> pair = null;
			try {
				pair = messages.poll();
				if (pair != null) {
					Session session = pair.getKey();
					MessageHandlerChain handlerChain = session.getHandlerChain();
					handlerChain.first().handle(handlerChain, session, pair.getValue());
				} else {
					Thread.sleep(10);
				}
			} catch (InterruptedException e) {
				logger.error("Failed in performer loop, InterruptedException! ", e);
			} catch (Exception e) {
				logger.error("Failed in performer loop! ", e);
			}
		}
	}

	public int queueSize() {
		return messages.size();
	}
}
